package finalapp.exercise.activities;

import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

import finalapp.exercise.R;
import finalapp.exercise.db.LocationsDB.Places;
import finalapp.exercise.util.CustomLocationListener;
import finalapp.exercise.util.CustomOverlay;

/**
 * Clase que muestra el mapa de localizaciones y permite crear una nueva
 * localizacion o bien mostrar los detalles de una ya existente
 * 
 * @author Alejandro Villamarin
 *
 */
public class MapaLugaresActivity extends MapActivity {
	
	
	/**
	 * Atributo MapView que muestra el mapa
	 */
	private MapView mapa;
	/**
	 * Atributo que usaremos para hacer zoom en el mapa
	 */
	private MapController mapController;
	
	/**
	 * Coleccion de objetos overlay que pondremos sobre el mapa
	 */
	private List<Overlay> mapOverlays;
	
	/**
	 * Atributo que nos permite asociar texto a hitos en el mapa y se encarga de los eventos onTap
	 */
	private CustomOverlay customOverlay;
	
	/**
	 * Variable que usaremos para centrar el mapa una vez cargado
	 */
	private double latitud;
	
	/**
	 * Variable que usaremos para centrar el mapa una vez cargado
	 */
	private double longitud;

	/**
	 * Latitud por defecto en el caso de que no haya ningun dato en la bd, en este caso, Zamudio
	 */
	private final double defaultLatitud = 43.28333;
	
	/**
	 * Longitud por defecto en el caso de que no haya ningun dato en la bd, en este caso, Zamudio
	 */
	private final double defaultLongitud = -2.86667;
	
	/**
	 * Variable que usaremos para identificar el dialogo de ayuda
	 */
	private static final int DIALOG_HELP = 0;	
	
	
	/**
	 * Metodo que se llama cuando se carga la Activity. En este caso cargamos el mapa con los datos de la bd y 
	 * si no hay ninguna localizacion lo centramos en Zamudio por defecto.
	 */
    @Override
    public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
	       
    	//asignamos el lugar por defecto para luego hacer el centrado
    	latitud = defaultLatitud;
    	longitud = defaultLongitud;
		
		//Establecemos el layout
		setContentView(R.layout.mapaactivity);
		//Obtenemos el layout para el mapa
		mapa = (MapView) findViewById(R.id.mapa);
		//Activamos el zoom
		mapa.displayZoomControls(true);
		mapa.setBuiltInZoomControls(true);
		//Establecemos el zoom y ponemos la vista de satelite
		mapController = mapa.getController();
		mapController.setZoom(16);
		mapa.setSatellite(true);
		//Obtenemos los overlays
		mapOverlays = mapa.getOverlays();
		//Obtenemos el marker custom para nuestros overlays
		Drawable drawable = this.getResources().getDrawable(R.drawable.marker);
		//creamos nuestro objeto ItemizedOverlayItem customizado
        customOverlay = new CustomOverlay(this, drawable);
        customOverlay.clear();
        //cargamos los objetos de la base de datos
        cargarLocalizaciones();
        //Centramos el mapa en el punto por defecto o en el ultimo que hemos obtenido de la bd (si no estaba vacia)
		GeoPoint geo = new GeoPoint((int) (latitud * 1E6), (int) (longitud * 1E6));
		mapController.setCenter(geo);
        mapOverlays.clear();
        mapOverlays.add(customOverlay);
        //0btenemos un LocationManager para gestionar los eventos relacionados con el uso del mapa
        LocationManager gestorLocations = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        CustomLocationListener mlistener = new CustomLocationListener(this, mapController);
        //monitorizamos los cambios en el proveedor de GPS
        gestorLocations.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, mlistener);
    }
    
    /**
     * Metodo que se llama cuando vuelve del modo stop
     */
    public void onRestart(){
    	super.onRestart();
    	//limpiamos las localizaciones
    	customOverlay.clear();
    	 // se ponen en el mapa todos los lugares de la base de datos
    	cargarLocalizaciones();
        //Centramos el mapa en el punto por defecto o en el ultimo que hemos obtenido de la bd (si no estaba vacia)
		GeoPoint geo = new GeoPoint((int) (latitud * 1E6), (int) (longitud * 1E6));
		mapController.setCenter(geo);
        mapOverlays.clear();
        mapOverlays.add(customOverlay);
    }
    
    /**
     * Metodo que se llama cuando vuelve del modo pause
     */
    public void onResume(){
    	super.onResume();
    	//limpiamos las localizaciones
    	customOverlay.clear();
    	 // se ponen en el mapa todos los lugares de la base de datos
    	cargarLocalizaciones();
        //Centramos el mapa en el punto por defecto o en el ultimo que hemos obtenido de la bd (si no estaba vacia)
		GeoPoint geo = new GeoPoint((int) (latitud * 1E6), (int) (longitud * 1E6));
		mapController.setCenter(geo);
        mapOverlays.clear();
        mapOverlays.add(customOverlay);
    }
    
    /**
     * Metodo que indica si estamos mostrando informacion de ruta de algun tipo. Como
     * en nuestro caso no lo hacemos, devolvemos false siempre.
     * 
     * @return	TRUE si se esta mostrando informacion de ruta de algun tipo
     */
	@Override
	protected boolean isRouteDisplayed() {
		//No hacemos nada, aunque deberiamos notificar a Google que se esta usando su servicio
		return false;
	}
	
	/**
	 * Metodo que se encarga de cargar las localizaciones almacenadas en la bd y volcarlas al mapa
	 */
	private void cargarLocalizaciones (){	
		
   		// Obtenemos todos las localizaciones de la BD
   		final String[] columnas = new String[] { Places._ID, Places.NAME, Places.LATITUDE, Places.LONGITUDE};
   		//Uri del proveedor 
   		Uri uri = Uri.parse("content://finalapp.exercise.db.locationsprovider/location");
   		//Ejecutamos la query
   		Cursor cursor = managedQuery(uri, columnas, null, null, Places.NAME);
   		 		
   		// Para que la actividad se encargue de manejar el cursor segun sus ciclos de vida
   		startManagingCursor(cursor);
   		
   		//Iteramos sobre el cursor
   		if (cursor != null) {

   			//Si hay algun elemento devuelto de la query, obtenemos los datos y creamos un marker en el mapa
            if (cursor.moveToFirst()) {
                do {
                	
                	//Obtenemos los campos del registro en curso
                	int idLoc = cursor.getInt(cursor.getColumnIndex(Places._ID));
                	String nombreLoc = cursor.getString(cursor.getColumnIndex(Places.NAME));
                	double longitudLoc = cursor.getDouble(cursor.getColumnIndex(Places.LONGITUDE));
                	double latitudLoc = cursor.getDouble(cursor.getColumnIndex(Places.LATITUDE));
                	//Añadimos una localizacion en el mapa
            		customOverlay.insertarLocalizacion(latitudLoc, longitudLoc, nombreLoc, idLoc);
            		//Actualizamos la longitud y latitud para el centrado en el ultimo punto obtenido
            		if (cursor.isLast()){
            			latitud = latitudLoc;
            			longitud = longitudLoc;
            		}                 
                } while (cursor.moveToNext());
            }
   		}
            

	}
	/**
	 * Metodo que añade un menu a la activity
	 * @param	menu	El objeto Menu a añadir
	 * @return	TRUE si se ha añadido el menu correctamente
	 */
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.menu_mapa, menu);
    	return true;
    }
	
	/**
	 * Este metodo se encarga de gestionar cada accion seleccionada en el menu de la activity
	 * 
	 *  @param	item	El elemento seleccionado en el menu
	 *  @return	TRUE si se ha podido mostrar la accion vinculada a la opcion seleccionada
	 */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	case R.id.menuAyudaMapa:
			showDialog(DIALOG_HELP);
   			return true;
    	case R.id.menuSalirMapa:
    		finish();
   			return true;
    	default:
    		return false;
    	}
    }
    
  	/**
   	 * Metodo que se muestra al abrir el dialogo
   	 * @param	id	El identificador de la opcion seleccionada
   	 * @return	El objeto Dialog vinculado al identificador
   	 */
   	@Override
   	protected Dialog onCreateDialog(int id) {
   		switch(id) {
   			case DIALOG_HELP:
   				
   				AlertDialog dialogHelp = null;
   				final AlertDialog.Builder builder;
   				LayoutInflater li = LayoutInflater.from(this);
   				View view = li.inflate(R.layout.ayuda_mapa, null);
   				builder = new AlertDialog.Builder(this).setIcon(R.drawable.icy_earth);
   				builder.setTitle(getString(R.string.app_name));
   				builder.setPositiveButton("Ok", null);
   				builder.setView(view);
   				dialogHelp = builder.create();
   				return dialogHelp;
   			default:
   				return null;
   		}
   	}
}
